package org.example.ServletServer.Engine;

import jakarta.servlet.*;
import org.example.ServletServer.Engine.Support.InitParameters;

import java.util.*;

public class FilterRegistrationImp implements FilterRegistration.Dynamic {
    final ServletContext context;
    final String name;
    final Filter filter;
    boolean initialized = false;

    final List<String> urlPatterns = new ArrayList<>(4);

    final InitParameters initParameters = new InitParameters();
    public FilterRegistrationImp(ServletContext context, String name, Filter filter) {
        this.context = context;
        this.name = name;
        this.filter = filter;
    }

    public FilterConfig getFilterConfig() {
        return new FilterConfig() {
            @Override
            public String getFilterName() {
                return name;
            }

            @Override
            public ServletContext getServletContext() {
                return context;
            }

            @Override
            public String getInitParameter(String s) {
                return initParameters.getInitParameter(s);
            }

            @Override
            public Enumeration<String> getInitParameterNames() {
                return initParameters.getInitParameterNames();
            }
        };
    }
    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getClassName() {
        return filter.getClass().getName();
    }

    @Override
    public boolean setInitParameter(String s, String s1) {
        checkNotInitialized("setInitParameter");
        return initParameters.setInitParameter(s,s1);
    }

    @Override
    public String getInitParameter(String s) {
        return initParameters.getInitParameter(s);
    }

    @Override
    public Set<String> setInitParameters(Map<String, String> map) {
        checkNotInitialized("setInitParameter");
        return initParameters.setInitParameters(map);
    }

    @Override
    public Map<String, String> getInitParameters() {
        return initParameters.getInitParameters();
    }
    @Override
    public void addMappingForServletNames(EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter, String... servletNames) {
        throw new UnsupportedOperationException("addMappingForServletNames");
    }

    @Override
    public Collection<String> getServletNameMappings() {
        return List.of();
    }

    @Override
    public void addMappingForUrlPatterns(EnumSet<DispatcherType> enumSet, boolean b, String... strings) {
        checkNotInitialized("addMappingForUrlPatterns");
        if (!enumSet.contains(DispatcherType.REQUEST) || enumSet.size() != 1) {
            throw new IllegalArgumentException("Only support DispatcherType.REQUEST.");
        }
        if (strings == null || strings.length == 0) {
            throw new IllegalArgumentException("Missing urlPatterns.");
        }
        for (String urlPattern : strings) {
            this.urlPatterns.add(urlPattern);
        }
    }

    @Override
    public Collection<String> getUrlPatternMappings() {
        return urlPatterns;
    }

    @Override
    public void setAsyncSupported(boolean isAsyncSupported) {
        checkNotInitialized("setInitParameter");
        if (isAsyncSupported) {
            throw new UnsupportedOperationException("Async is not supported.");
        }
    }

    private void checkNotInitialized(String name) {
        if (this.initialized) {
            throw new IllegalStateException("Cannot call " + name + " after initialization.");
        }
    }
}
